package com.thoughtworks.shoutbox.server;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.thoughtworks.shoutbox.client.dto.ShoutDTO;
import com.thoughtworks.shoutbox.client.services.ShoutingService;
import com.thoughtworks.shoutbox.server.models.Room;
import com.thoughtworks.shoutbox.server.models.Shout;
import com.thoughtworks.shoutbox.server.models.UserDetails;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class ShoutingServiceImpl extends RemoteServiceServlet implements
		ShoutingService {
	public void shout(String message, String roomId) {
		PersistenceManager persistenceManager = getPersistanceManager();
		try {
			Shout shout = new Shout(message, createUser(UserServiceFactory
					.getUserService().getCurrentUser()), roomId);
			persistenceManager.makePersistent(shout);
		} finally {
			persistenceManager.close();
		}
	}

	private PersistenceManager getPersistanceManager() {
		return PMF.get().getPersistenceManager();
	}

	private UserDetails createUser(User currentUser) {
		return new UserDetails(currentUser.getEmail(), currentUser
				.getNickname());
	}

	public ArrayList<ShoutDTO> getAllShouts(String roomId) {
		PersistenceManager persistenceManager = getPersistanceManager();
		try {
			ArrayList<ShoutDTO> shouts = new ArrayList<ShoutDTO>();
			javax.jdo.Query query = persistenceManager.newQuery(Shout.class,
					"roomId == '" + roomId + "'");

			Collection shoutsExtent = (Collection) query.execute();
			for (Object object : shoutsExtent) {
				Shout shout = (Shout) object;
				shouts.add(new ShoutDTO(shout.getUser().getNickname(), shout
						.getMessage()));
			}
			return shouts;
		} finally {
			persistenceManager.close();
		}
	}

	@Override
	public void createRoom(String roomName) {
		Room room = new Room(roomName);
		PersistenceManager persistenceManager = getPersistanceManager();
		try {
			persistenceManager.makePersistent(room);
		} finally {
			persistenceManager.close();
		}
	}

	@Override
	public Map<String, String> getAllRooms() {
		LinkedHashMap<String, String> roomIdAndNameMap = new LinkedHashMap<String, String>();
		PersistenceManager persistenceManager = getPersistanceManager();
		try {
			Extent<Room> roomsExtent = persistenceManager.getExtent(Room.class);
			for (Room room : roomsExtent) {
				roomIdAndNameMap.put(room.getId(), room.getName());
			}
		} finally {
			persistenceManager.close();
		}
		return roomIdAndNameMap;
	}

}
